home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gchess40.lha / gnuchess4.0p62 / src / main.c < prev    next >
C/C++ Source or Header  |  1993-06-22  |  12KB  |  502 lines

  1. /*
  2.  * main.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include "version.h"
  25. #include "gnuchess.h"
  26. #include <signal.h>
  27. char *ColorStr[2];
  28. char *CP[CPSIZE];
  29.  
  30. /*
  31.  * In a networked enviroment gnuchess might be compiled on different hosts
  32.  * with different random number generators, that is not acceptable if they
  33.  * are going to share the same transposition table.
  34.  */
  35. unsigned long int next = 1;
  36.  
  37. unsigned int
  38. urand (void)
  39. {
  40.   next *= 1103515245;
  41.   next += 12345;
  42.   return ((unsigned int) (next >> 16) & 0xFFFF);
  43. }
  44.  
  45. void
  46. gsrand (unsigned int seed)
  47. {
  48.   next = seed;
  49. }
  50.  
  51. unsigned long hashkey, hashbd;
  52. struct hashval hashcode[2][7][64];
  53.  
  54. #ifdef ttblsz
  55. struct hashentry huge *ttable[2];
  56. unsigned int ttblsize;
  57. #endif
  58. #ifdef BINBOOK
  59. extern char *binbookfile;
  60. #endif
  61. extern char *bookfile;
  62.  
  63. char savefile[128] = "";
  64. char listfile[128] = "";
  65. #ifdef HISTORY
  66. unsigned short history[32768];
  67. #endif
  68. short svalue[64];
  69. short rpthash[2][256];
  70. struct leaf Tree[TREE], *root;
  71. short TrPnt[MAXDEPTH];
  72. short PieceList[2][64], PawnCnt[2][8];
  73. short castld[2], Mvboard[64];
  74. struct flags flag;
  75. short opponent, computer, WAwindow, WBwindow, BAwindow, BBwindow, dither,
  76.   INCscore;
  77. long ResponseTime, ExtraTime, MaxResponseTime, et, et0, time0, ft;
  78. unsigned long GenCnt, NodeCnt, ETnodes, EvalNodes, HashCnt, HashAdd, FHashCnt, FHashAdd, HashCol, THashCol, filesz, hashmask, hashbase;
  79. long replus, reminus;
  80. short HashDepth = HASHDEPTH, HashMoveLimit = HASHMOVELIMIT;
  81. short player, xwndw;
  82. /*unsigned*/ short rehash; /* -1 is used as a flag --tpm */
  83. struct GameRec GameList[MAXMOVES + MAXDEPTH];
  84. short Sdepth, Game50, MaxSearchDepth;
  85. short GameCnt = 0;
  86. short epsquare, contempt;
  87. int Book;
  88. struct TimeControlRec TimeControl;
  89. int TCadd = 0;
  90. short TCflag, TCmoves, TCminutes, TCseconds, OperatorTime;
  91. short XCmoves[3], XCminutes[3], XCseconds[3], XC, XCmore;
  92. const short otherside[3] =
  93. {black, white, neutral};
  94. unsigned short hint;
  95. short int TOflag;        /* force search re-init if we backup search */
  96.  
  97. short mtl[2], pmtl[2], hung[2];
  98. short Pindex[64];
  99. short PieceCnt[2];
  100. short FROMsquare, TOsquare;
  101. short HasKnight[2], HasBishop[2], HasRook[2], HasQueen[2];
  102. short ChkFlag[MAXDEPTH], CptrFlag[MAXDEPTH], PawnThreat[MAXDEPTH];
  103. short Pscore[MAXDEPTH], Tscore[MAXDEPTH];
  104. const short qrook[3] =
  105. {0, 56, 0};
  106. const short krook[3] =
  107. {7, 63, 0};
  108. const short kingP[3] =
  109. {4, 60, 0};
  110. const short rank7[3] =
  111. {6, 1, 0};
  112. const short sweep[8] =
  113. {false, false, false, true, true, true, false, false};
  114. unsigned short killr0[MAXDEPTH], killr1[MAXDEPTH];
  115. unsigned short killr2[MAXDEPTH], killr3[MAXDEPTH];
  116. unsigned short PV, SwagHt, Swag0, Swag1, Swag2, Swag3, Swag4, sidebit;
  117. #ifdef KILLT
  118. short killt[0x4000];
  119. #endif
  120. const short value[7] =
  121. {0, valueP, valueN, valueB, valueR, valueQ, valueK};
  122. const short control[7] =
  123. {0, ctlP, ctlN, ctlB, ctlR, ctlQ, ctlK};
  124. short stage, stage2, Developed[2];
  125. FILE *hashfile;
  126. unsigned int starttime;
  127. short int ahead = true, hash = true;
  128.  
  129. #if defined CHESSTOOL || defined XBOARD
  130. void
  131. TerminateChess (int sig)
  132. {
  133.   ExitChess ();
  134. }
  135.  
  136. #endif
  137. int timeopp[MINGAMEIN], timecomp[MINGAMEIN];
  138. int compptr, oppptr;
  139. inline void
  140. TimeCalc ()
  141. {
  142. /* adjust number of moves remaining in gamein games */
  143.   int increment = 0;
  144.   int topsum = 0;
  145.   int tcompsum = 0;
  146.   int me,him;
  147.   int i;
  148. /* dont do anything til you have enough numbers */
  149.   if (GameCnt < (MINGAMEIN * 2)) return;
  150. /* calculate average time in sec for last MINGAMEIN moves */
  151.   for (i = 0; i < MINGAMEIN; i++)
  152.     {
  153.       tcompsum += timecomp[i];
  154.       topsum += timeopp[i];
  155.     }
  156.   topsum /= (100 * MINGAMEIN);
  157.   tcompsum /= (100 * MINGAMEIN);
  158. /* if I have less time than opponent add another move */
  159.     me = TimeControl.clock[computer]/100; 
  160.     him = TimeControl.clock[opponent]/100;
  161.     if(me < him) increment += 2;
  162.     if((him - me) > 60 || (me<him && me < 120))increment++;
  163. /* if I am losing more time with each move add another */
  164.   /*if ( !((me - him) > 60) && tcompsum > topsum) increment++;*/
  165.   if ( tcompsum > topsum) increment +=2;
  166. /* but dont let moves go below MINMOVES */
  167.   else if (TimeControl.moves[computer] < MINMOVES && !increment) increment++;
  168. /* if I am doing really well use more time per move */
  169.   else if (me > him && tcompsum < topsum) increment = -1;
  170. /* if not fischer clock be careful about time */
  171.   if(TCadd == 0 && increment >0)increment += 2;
  172.   if(me == 0 && increment >0)increment += 2;
  173.   TimeControl.moves[computer] += increment;
  174. }
  175.  
  176. /* hmm.... shouldn`t main be moved to the interface routines */
  177. int
  178. main (int argc, char **argv)
  179. {
  180.   char *xwin = 0;
  181.   char *Lang = NULL;
  182.   gsrand (starttime = ((unsigned int) time ((long *) 0)));    /* init urand */
  183. #ifdef ttblsz
  184.   ttblsize = ttblsz;
  185.   rehash = -1;
  186. #endif /* ttblsz */
  187.   if (argc > 2)
  188.     {
  189.       if (argv[1][0] == '-' && argv[1][1] == 'L')
  190.     {
  191.       Lang = argv[2];
  192.       argv += 2;
  193.       argc -= 2;
  194.     }
  195.     }
  196.   InitConst (Lang);
  197.   ColorStr[0] = CP[118];
  198.   ColorStr[1] = CP[119];
  199.  
  200.   while (argc > 1 && ((argv[1][0] == '-') || (argv[1][0] == '+')))
  201.     {
  202.       switch (argv[1][1])
  203.     {
  204.     case 'a':
  205.       ahead = ((argv[1][0] == '-') ? false : true);
  206.       break;
  207.     case 'b':
  208.       argv++;
  209.       argc--;
  210.       if (argc > 1)
  211.         {
  212.           bookfile = argv[1];
  213. #ifdef BINBOOK
  214.           binbookfile = NULL;
  215. #endif
  216.         }
  217.       break;
  218. #ifdef BINBOOK
  219.     case 'B':
  220.       argv++;
  221.       argc--;
  222.       if (argc > 1)
  223.         binbookfile = argv[1];
  224.       break;
  225. #endif
  226.     case 'h':
  227.       hash = ((argv[1][0] == '-') ? false : true);
  228.       break;
  229.     case 's':
  230.       argc--;
  231.       argv++;
  232.       if (argc > 1)
  233.         strcpy (savefile, argv[1]);
  234.       break;
  235.     case 'l':
  236.       argc--;
  237.       argv++;
  238.       if (argc > 1)
  239.         strcpy (listfile, argv[1]);
  240.       break;
  241. #ifndef GDBM
  242.     case 'S':
  243.       argc--;
  244.       argv++;
  245.       if(argc > 1)booksize = atoi(argv[1]);
  246.       break;
  247. #endif
  248.     case 'P':
  249.       argc--;
  250.       argv++;
  251.       if(argc > 1)bookmaxply = atoi(argv[1]);
  252.       break;
  253.  
  254. #if ttblsz
  255.     case 'r':
  256.       if (argc > 2)
  257.         rehash = atoi (argv[2]);
  258.       argc--;
  259.       argv++;
  260.       if (rehash > MAXrehash)
  261.         rehash = MAXrehash;
  262.       break;
  263.     case 'T':
  264.       if (argc > 2)
  265.         ttblsize = atoi (argv[2]);
  266.       argc--;
  267.       argv++;
  268.       if ((ttblsize <= MINTTABLE)) ttblsize = (MINTTABLE)+1;
  269.       break;
  270. #ifdef HASHFILE
  271.     case 't':        /* create or test persistent transposition
  272.                  * table */
  273.       hashfile = fopen (HASHFILE, RWA_ACC);
  274.       if (hashfile)
  275.         {
  276.           fseek (hashfile, 0L, SEEK_END);
  277.           filesz = (ftell (hashfile) / sizeof (struct fileentry)) - 1;
  278.         }
  279.       if (hashfile != NULL)
  280.         {
  281.           long i, j;
  282.           int nr[MAXDEPTH];
  283.           struct fileentry n;
  284.  
  285.           printf (CP[49]);
  286.           for (i = 0; i < MAXDEPTH; i++)
  287.         nr[i] = 0;
  288.           fseek (hashfile, 0L, SEEK_END);
  289.           i = ftell (hashfile) / sizeof (struct fileentry);
  290.           fseek (hashfile, 0L, SEEK_SET);
  291.           for (j = 0; j < i + 1; j++)
  292.         {
  293.           fread (&n, sizeof (struct fileentry), 1, hashfile);
  294. if(n.depth >MAXDEPTH) {printf("ERROR\n");exit(1);}
  295.           if (n.depth)
  296.             {
  297.               nr[n.depth]++;
  298.               nr[0]++;
  299.             }
  300.         }
  301.           printf (CP[109],
  302.               nr[0], i);
  303.           for (j = 1; j < MAXDEPTH; j++)
  304.         printf ("%d ", nr[j]);
  305.           printf ("\n");
  306.         }
  307.       return 0;
  308.     case 'c':        /* create or test persistent transposition
  309.                  * table */
  310.       if (argc > 2)
  311.         filesz = atoi (argv[2]);
  312.       if (filesz > 0 && filesz < 24)
  313.         filesz = (1 << filesz) - 1 + MAXrehash;
  314.         filesz = filesz + MAXrehash;
  315.       if ((hashfile = fopen (HASHFILE, RWA_ACC)) == NULL)
  316.         hashfile = fopen (HASHFILE, WA_ACC);
  317.       if (hashfile != NULL)
  318.         {
  319.           long j;
  320.           struct fileentry n;
  321.  
  322.           printf (CP[66]);
  323.           n.f = n.t = 0;
  324.           n.flags = 0;
  325.           n.depth = 0;
  326.           n.sh = n.sl = 0;
  327.           for (j = 0; j < filesz + 1; j++)
  328.         fwrite (&n, sizeof (struct fileentry), 1, hashfile);
  329.           fclose (hashfile);
  330.         }
  331.       else
  332.         printf (CP[50], HASHFILE);
  333.       return (0);
  334. #endif /* HASHFILE */
  335. #endif /* ttblsz */
  336.     case 'x':
  337.       xwin = &argv[1][2];
  338.       break;
  339.     case 'v':
  340.       fprintf (stderr, CP[102], version, patchlevel);
  341.       exit (1);
  342.     default:
  343.       fprintf (stderr, CP[113]);
  344.       exit (1);
  345.     }
  346.       argv++;
  347.       argc--;
  348.     }
  349.   XC = 0;
  350.   MaxResponseTime = 0;
  351. #if defined CHESSTOOL || defined XBOARD
  352.   signal (SIGTERM, TerminateChess);
  353.   TCflag = true;
  354.   TCmoves = 40;
  355.   TCminutes = 5;
  356.   TCseconds = 0;
  357.   TCadd = 0;
  358.   OperatorTime = 0;
  359. #else
  360.   TCflag = false;
  361.   OperatorTime = 0;
  362. #endif
  363.   if (argc == 2)
  364.     {
  365.       char *p;
  366.  
  367.       MaxResponseTime = 100L * strtol (argv[1], &p, 10);
  368.       if (*p == ':')
  369.     MaxResponseTime = 60L * MaxResponseTime +
  370.       100L * strtol (++p, (char **) NULL, 10);
  371.       TCflag = false;
  372.       TCmoves = 0;
  373.       TCminutes = 0;
  374.       TCseconds = 0;
  375.     }
  376.   if (argc >= 3)
  377.     {
  378.       char *p;
  379.       if (argc > 9)
  380.     {
  381.       printf ("%s\n", CP[220]);
  382.       exit (1);
  383.     }
  384.       TCmoves = atoi (argv[1]);
  385.       TCminutes = (short)strtol (argv[2], &p, 10);
  386.       if (*p == ':')
  387.     TCseconds = (short)strtol (p + 1, (char **) NULL, 10);
  388.       else
  389.     TCseconds = 0;
  390.       TCflag = true;
  391.       argc -= 3;
  392.       argv += 3;
  393.       while (argc > 1)
  394.     {
  395.       XCmoves[XC] = atoi (argv[0]);
  396.       XCminutes[XC] = (short)strtol (argv[1], &p, 10);
  397.       if (*p == ':')
  398.         XCseconds[XC] = (short)strtol (p + 1, (char **) NULL, 10);
  399.       else
  400.         XCseconds[XC] = 0;
  401.       if (XCmoves[XC] && (XCminutes[XC] || XCseconds[XC]))
  402.         XC++;
  403.       else
  404.         {
  405.           printf (CP[220]);
  406.           exit (1);
  407.         }
  408.       argc -= 2;
  409.       argv += 2;
  410.     }
  411.       if (argc)
  412.     {
  413.       printf ("%s\n", CP[220]);
  414.       exit (1);
  415.     }
  416.     }
  417.   Initialize ();
  418.   Initialize_dist ();
  419.   Initialize_moves ();
  420.   NewGame ();
  421.  
  422.   flag.easy = ahead;
  423.   flag.hash = hash;
  424.   if (xwin)
  425.     xwndw = atoi (xwin);
  426.  
  427.   hashfile = NULL;
  428. #if ttblsz
  429. #ifdef HASHFILE
  430.   hashfile = fopen (HASHFILE, RWA_ACC);
  431.   if (hashfile)
  432.     {
  433.       fseek (hashfile, 0L, SEEK_END);
  434.       filesz = ftell (hashfile) / sizeof (struct fileentry) - 1 - MAXrehash;
  435.               hashmask = filesz>>1;
  436.           hashbase = hashmask+1;
  437.     }
  438. #if !defined CHESSTOOL && !defined XBOARD
  439.   else
  440.     ShowMessage (CP[98]);
  441. #endif
  442. #endif /* HASHFILE */
  443. #endif /* ttblsz */
  444.   while (!(flag.quit))
  445.     {
  446.       oppptr = (oppptr + 1) % MINGAMEIN;
  447.       if (flag.bothsides && !flag.mate)
  448.     SelectMove (opponent, 1);
  449.       else
  450.     InputCommand ();
  451.       if (opponent == black)
  452.     if (flag.gamein || TCadd)
  453.       {
  454.         TimeCalc ();
  455.       }
  456.     else if (TimeControl.moves[opponent] == 0)
  457.       {
  458.         if (XC)
  459.           if (XCmore < XC)
  460.         {
  461.           TCmoves = XCmoves[XCmore];
  462.           TCminutes = XCminutes[XCmore];
  463.           TCseconds = XCseconds[XCmore];
  464.           XCmore++;
  465.         }
  466.         SetTimeControl ();
  467.       }
  468.  
  469.       compptr = (compptr + 1) % MINGAMEIN;
  470.       if (!(flag.quit || flag.mate || flag.force))
  471.     {
  472.       SelectMove (computer, 1);
  473.       if (computer == black)
  474.         if (flag.gamein)
  475.           {
  476.         TimeCalc ();
  477.           }
  478.         else if (TimeControl.moves[computer] == 0)
  479.           {
  480.         if (XC)
  481.           if (XCmore < XC)
  482.             {
  483.               TCmoves = XCmoves[XCmore];
  484.               TCminutes = XCminutes[XCmore];
  485.               TCseconds = XCseconds[XCmore];
  486.               XCmore++;
  487.             }
  488.         SetTimeControl ();
  489.           }
  490.     }
  491.     }
  492. #if ttblsz
  493. #ifdef HASHFILE
  494.   if (hashfile)
  495.     fclose (hashfile);
  496. #endif /* HASHFILE */
  497. #endif /* ttblsz */
  498.  
  499.   ExitChess ();
  500.   return (0);
  501. }
  502.